package com.icesoft.system.starter;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSONArray;
import com.icesoft.framework.core.entity.Dictionary;
import com.icesoft.framework.core.util.PathUtil;
import com.icesoft.framework.core.vo.DictionaryVO;
import com.icesoft.system.annotation.ConstructDictionary;
import com.icesoft.system.service.impl.DictionaryServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

@Slf4j
@Order(Integer.MIN_VALUE)
@Component
@RequiredArgsConstructor
public class ConstructDictionaryStarter implements ApplicationRunner {

	private final DictionaryServiceImpl dictionaryService;

	private final ApplicationContext context;

	@Override
	public void run(ApplicationArguments args) throws Exception {
		if (dictionaryService.count() == 0) {
			String json = IoUtil.readUtf8(PathUtil.getPathInputStream("META-INF/json/dictionary.json"));
			List<DictionaryVO> dictionaryList = JSONArray.parseArray(json, DictionaryVO.class);
			for (DictionaryVO dictionary : dictionaryList) {
				dictionaryService.createDictAndChildren(dictionary);
			}
		}

		Map<String, Object> listenerBeans = context.getBeansWithAnnotation(ConstructDictionary.class);
		listenerBeans.forEach((type, bean) -> {
			ConstructDictionary annotation = bean.getClass().getAnnotation(ConstructDictionary.class);
			List<Dictionary> itemsList = dictionaryService.getByType(annotation.value());

			for (Field field : bean.getClass().getDeclaredFields()) {
				for (Dictionary dictionary : itemsList) {
					if (dictionary.getItemCode().equals(field.getName())) {
						try {
							String typeName = bean.getClass().getDeclaredField(field.getName()).getType().getSimpleName();
							if (typeName.equals("boolean") || typeName.equals("Boolean")) {
								bean.getClass().getDeclaredField(field.getName()).set(bean, Boolean.parseBoolean(dictionary.getItemValue()));
							}

							if (typeName.equals("int") || typeName.equals("Integer")) {
								bean.getClass().getDeclaredField(field.getName()).set(bean, Integer.parseInt(dictionary.getItemValue()));
							}

							if (typeName.equals("String")) {
								bean.getClass().getDeclaredField(field.getName()).set(bean, dictionary.getItemValue());
							}


						} catch (NoSuchFieldException | IllegalAccessException e) {
							throw new RuntimeException(e);
						}
					}
				}
			}
		});
	}
}
